package com.bank.bank.transaction.service.impl;

import com.bank.bank.base.exception.ServiceException;
import com.bank.bank.base.response.StatusCode;
import com.bank.bank.transaction.mapper.TransactionMapper;
import com.bank.bank.transaction.pojo.dto.DrawMoneyParam;
import com.bank.bank.transaction.pojo.dto.SaveMoneyParam;
import com.bank.bank.transaction.pojo.dto.TransferMoneyParam;
import com.bank.bank.transaction.pojo.entity.Transaction;
import com.bank.bank.transaction.pojo.vo.DrawMoneyVO;
import com.bank.bank.transaction.pojo.vo.SaveMoneyVO;
import com.bank.bank.transaction.pojo.vo.TransactionDetailVO;
import com.bank.bank.transaction.service.TransactionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * Transactional注解: 事务注解;
 */
@Slf4j
@Service
@Transactional
public class TransactionServiceImpl implements TransactionService {
    @Autowired
    private TransactionMapper transactionMapper;

    /**
     * 1.存款业务
     * @param saveMoneyParam to_account_id、amount
     * @return
     */
    @Override
    public SaveMoneyVO deposit(SaveMoneyParam saveMoneyParam) {
        log.debug("存款业务:saveMoneyParam={}", saveMoneyParam);
        //1.存入数据[mapper层接口-交易表中]
        Transaction transaction = new Transaction();
        BeanUtils.copyProperties(saveMoneyParam, transaction);
        transaction.setType("DEPOSIT");
        transaction.setCreatedAt(new Date());
        transactionMapper.saveMoneyInsertTransaction(transaction);
        //2.更新账户的余额[mapper层接口-账户表中]
        transactionMapper.saveMoneyUpdateTransactionByToAccountId(saveMoneyParam);
        //3.查询最新数据[mapper层接口-交易表和账户表联查]
        SaveMoneyVO saveMoneyVO = transactionMapper.saveMoneySelectTransactionInfo(transaction);

        return saveMoneyVO;
    }

    /**
     * 2.取款功能业务
     * @param drawMoneyParam
     * @return
     */
    @Override
    public DrawMoneyVO withdraw(DrawMoneyParam drawMoneyParam) {
        log.debug("取款功能业务:drawMoneyParam={}", drawMoneyParam);
        //1.查询余额,进行判断;
        Integer fromAccountId = drawMoneyParam.getFromAccountId();
        Double amount = drawMoneyParam.getAmount();
        Double balance = transactionMapper.selectBalanceByFromAccountId(fromAccountId);
        if (balance < amount) {//余额不足
            throw new ServiceException(StatusCode.MONEY_NOT_ENOUGH);
        }
        //2.交易表中插入交易记录;
        Transaction transaction = new Transaction();
        BeanUtils.copyProperties(drawMoneyParam, transaction);
        transaction.setType("WITHDRAW");
        transaction.setCreatedAt(new Date());
        transactionMapper.saveMoneyInsertTransaction(transaction); //复用存款的方法;
        //3.账户表中更新账户余额;
        transactionMapper.drawMoneyUpdateTransactionByFromAccountId(drawMoneyParam);
        //4.查询最新交易信息;
        DrawMoneyVO drawMoneyVO = transactionMapper.drawMoneySelectTransactionInfo(transaction);

        return drawMoneyVO;
    }

    /**
     * 3.转账功能
     * @param transferMoneyParam
     */
    @Override
    public void transfer(TransferMoneyParam transferMoneyParam) {
        log.debug("转账业务:transferMoneyParam={}", transferMoneyParam);
        //1.查询源账户余额from_account_id,并进行判断;
        Integer fromAccountId = transferMoneyParam.getFromAccountId();
        Double amount = transferMoneyParam.getAmount();
        Double balance = transactionMapper.selectBalanceByFromAccountId(fromAccountId);
        if (balance < amount) {
            throw new ServiceException(StatusCode.MONEY_NOT_ENOUGH);
        }

        //2.交易表中插入数据;
        Transaction transaction = new Transaction();
        BeanUtils.copyProperties(transferMoneyParam, transaction);
        transaction.setType("TRANSFER");
        transaction.setCreatedAt(new Date());
        transactionMapper.saveMoneyInsertTransaction(transaction); //复用的插入交易记录方法

        //3.账户表中更新源账户的余额from_account_id;
        DrawMoneyParam drawMoneyParam = new DrawMoneyParam();
        BeanUtils.copyProperties(transferMoneyParam, drawMoneyParam);
        transactionMapper.drawMoneyUpdateTransactionByFromAccountId(drawMoneyParam); //复用方法

        //4.账户表中更新目标账户的余额to_account_id;
        SaveMoneyParam saveMoneyParam = new SaveMoneyParam();
        BeanUtils.copyProperties(transferMoneyParam, saveMoneyParam);
        transactionMapper.saveMoneyUpdateTransactionByToAccountId(saveMoneyParam); //复用方法
    }

    /**
     * 4.查询交易详情
     * @param transactionId 交易id
     * @return
     */
    @Override
    public TransactionDetailVO getTransaction(String transactionId) {
        log.debug("查询交易详情业务:transactionId={}", transactionId);
        TransactionDetailVO transactionDetailVO = transactionMapper.selectTransactionInfoById(transactionId);
        return transactionDetailVO;
    }
}



















